<template>
  <div
    :id="container.substr(1)"
    class="editor-container"
    :class="{
      'preview-mode': page.preview?.enabled,
      'editor-is-fullscreen': fullscreen,
    }"
    :style="{
      height: props.height,
      zIndex: fullscreen ? props.fullscreenZIndex : 'unset',
    }"
  >
    <!-- 工具栏 - 固定顶部 -->
    <header class="editor-toolbar">
      <Toolbar />
    </header>

    <!-- 主内容区域 - 可滚动 -->
    <main class="editor-main">
      <!-- 大纲面板 - 显示在内容区域左侧 -->
      <OutlinePanel />
      <div class="editor-main-content">
        <EditorContainer />
      </div>
      <!-- 批注面板 - 显示在内容区域 -->
      <CommentPanel @select-comment="handleSelectComment" />
    </main>

    <!-- 状态栏 - 固定底部 -->
    <EditorFooter />
  </div>
</template>

<script setup lang="ts">
import { provide, onBeforeUnmount, onMounted, watch, ref } from "vue";
import { Editor } from "@tiptap/vue-3";
import Toolbar from "./components/toolbar";
import EditorFooter from "./components/container/footer.vue";
import EditorContainer from "./components/container/Page.vue";
import CommentPanel from "./components/comment/CommentPanel.vue";
import OutlinePanel from "./components/outline/OutlinePanel.vue";
import type { EditorProps, PageOption, PageSize } from "./types";
import { defaultDicts, defaultWebPages } from "./config/constants";
import { shortId } from "./utils";
import {
  addHistory,
  undoHistoryRecord,
  redoHistoryRecord,
  type HistoryRecords,
} from "./utils/history";
import { setTheme, type Theme } from "./utils/theme";
import { removeAllHotkeys } from "./utils/useHotKey";
import { commentStore, commentActions } from "./store/comment";

defineOptions({
  name: "Editor",
});

const props = withDefaults(defineProps<EditorProps>(), {
  editorKey: "default",
  locale: "zh-CN",
  theme: "light",
  height: "100%",
  fullscreenZIndex: 10,
  dicts: () => defaultDicts,
  toolbar: () => ({
    mode: "ribbon",
  }),
  page: () => ({
    layout: "page",
    layouts: ["page", "web"],
    defaultMargin: {
      left: 3.18,
      right: 3.18,
      top: 2.54,
      bottom: 2.54,
    },
    defaultOrientation: "portrait",
    defaultBackground: "#fff",
    showBreakMarks: true,
    showLineNumber: false,
    showBookmark: false,
    showToc: false,
    watermark: {
      type: "compact",
      alpha: 0.2,
      fontColor: "#000",
      fontSize: 16,
      fontFamily: "SimSun",
      fontWeight: "normal",
      text: "",
    },
  }),
  document: () => ({
    title: "",
    content: "",
    placeholder: {
      en_US: "Please enter the document content...",
      zh_CN: "请输入文档内容...",
    },
    enableSpellcheck: true,
    enableMarkdown: true,
    enableBubbleMenu: true,
    enableBlockMenu: true,
    readOnly: false,
    autofocus: true,
    characterLimit: 0,
    typographyRules: {},
    // https://prosemirror.net/docs/ref/#view.EditorProps
    editorProps: {},
    // https://prosemirror.net/docs/ref/#model.ParseOptions
    parseOptions: {
      preserveWhitespace: "full",
    },
    autoSave: {
      enabled: true,
      interval: 300000,
    },
  }),
  webPages: () => defaultWebPages,
  templates: () => [],
  shareUrl: location.href || "",
  extensions: () => [],
  disableExtensions: () => [],
});

const emits = defineEmits([
  "beforeCreate",
  "created",
  "changed",
  "changed:selection",
  "changed:transaction",
  "changed:menu",
  "changed:toolbar",
  "changed:pageLayout",
  "changed:pageSize",
  "changed:pageOrientation",
  "changed:pageMargin",
  "changed:pageBackground",
  "changed:pageShowToc",
  "changed:pagePreview",
  "changed:pageZoom",
  "changed:pageWatermark",
  "changed:locale",
  "changed:theme",
  "contentError",
  "print",
  "focus",
  "blur",
  "saved",
  "destroy",
  "menuChange",
]);

// 撤销重做的记录步骤
const historyRecords = ref<HistoryRecords>({
  done: [], // 能撤销的记录数组
  undone: [], // 能重做的记录数组
  isUndoRedo: false, // 标记是否正在执行撤销/重做操作
});

const container = ref(`#editor-${shortId(4)}`);
const defaultOptions = inject("defaultOptions", {});
const editor = ref<Editor | null>(null);
const savedAt = ref<Date | null>(null);
// 提供给子组件使用的 document 配置（供 editor/index.vue 注入）
const $document = ref(props.document);
const page = ref<PageOption>({
  layout: "page",
  layouts: ["page", "web"],
  defaultMargin: {
    left: 3.18,
    right: 3.18,
    top: 2.54,
    bottom: 2.54,
  },
  defaultOrientation: "portrait",
  defaultBackground: "#fff",
  showBreakMarks: true,
  showLineNumber: false,
  showBookmark: false,
  showToc: false,
  watermark: {
    type: "compact",
    alpha: 0.2,
    fontColor: "#000",
    fontSize: 16,
    fontFamily: "SimSun",
    fontWeight: "normal",
    text: "",
  },
});
const blockMenu = ref(false);
const fullscreen = ref(false);
const destroyed = ref(false);

// 自动保存相关
let contentUpdated = ref(false);
let isFirstUpdate = ref(true);
let autoSaveInterval = ref<ReturnType<typeof setInterval> | null>(null);

// 大纲面板显示状态
const outlineVisible = ref(false);

provide("editor", editor);
provide("container", container);
provide("defaultOptions", defaultOptions);
provide("savedAt", savedAt);
provide("page", page);
provide("document", $document);
provide("blockMenu", blockMenu);
provide("destroyed", destroyed);
provide("historyRecords", historyRecords);
provide("fullscreen", fullscreen);
provide("editorProps", props);
provide("outlineVisible", outlineVisible);

// 生命周期管理
onMounted(() => {
  setTheme(props.theme);
});

onBeforeUnmount(() => {
  clearAutoSaveInterval();

  // 清理编辑器事件监听
  if (editor.value) {
    if (createHandler) editor.value.off("create", createHandler);
    if (updateHandler) editor.value.off("update", updateHandler);
    if (selectionUpdateHandler)
      editor.value.off("selectionUpdate", selectionUpdateHandler);
    if (transactionHandler) editor.value.off("transaction", transactionHandler);
    if (focusHandler) editor.value.off("focus", focusHandler);
    if (blurHandler) editor.value.off("blur", blurHandler);
    if (destroyHandler) editor.value.off("destroy", destroyHandler);

    // 置空引用
    createHandler = null;
    updateHandler = null;
    selectionUpdateHandler = null;
    transactionHandler = null;
    focusHandler = null;
    blurHandler = null;
    destroyHandler = null;
  }

  destroy();
  // 清除所有绑定的快捷键
  removeAllHotkeys();
});

// 页面配置监听
watch(
  () => props.page,
  ({
    layouts,
    defaultBackground,
    defaultMargin,
    defaultOrientation,
    watermark,
    showBreakMarks,
    showBookmark,
    showLineNumber,
    showToc,
  }: PageOption) => {
    page.value = {
      layout: "page",
      layouts,
      defaultMargin,
      defaultBackground,
      defaultOrientation,
      watermark,
      showBreakMarks,
      showBookmark,
      showLineNumber,
      showToc,
      size: props.dicts?.pageSizes?.find((item: PageSize) => item?.default)
        ? { ...props.dicts.pageSizes.find((item: PageSize) => item?.default)! }
        : undefined,
      margin: defaultMargin,
      background: defaultBackground,
      orientation: defaultOrientation,
      zoomLevel: 100,
      autoWidth: false,
      preview: {
        enabled: false,
        laserPointer: false,
      },
    };
  },
  { deep: true, immediate: true }
);

// 只读模式监听
watch(
  () => props.document?.readOnly,
  (readOnly?: boolean) => {
    editor.value?.setEditable(!readOnly);
  },
  { immediate: true }
);

// 主题监听
watch(
  () => props.theme,
  (theme: Theme) => {
    setTheme(theme);
  }
);

// 同步 props.document 到注入的 $document，保持与子组件一致
watch(
  () => props.document,
  (val) => {
    $document.value = val;
  },
  { deep: true, immediate: true }
);

// 自动保存监听
watch(
  () => contentUpdated.value,
  (val: boolean) => {
    const { autoSave } = props.document ?? {};
    if (!autoSave?.enabled) {
      return;
    }
    if (isFirstUpdate.value) {
      isFirstUpdate.value = false;
      setTimeout(() => {
        contentUpdated.value = false;
      });
      return;
    }
    if (!val) {
      clearAutoSaveInterval();
      return;
    }
    autoSaveInterval.value = setInterval(() => {
      void saveContent();
      contentUpdated.value = false;
      clearAutoSaveInterval();
    }, autoSave.interval);
  }
);

// 编辑器事件监听 - 保存事件处理函数引用以便正确清理
let createHandler: (({ editor }: { editor: any }) => void) | null = null;
let updateHandler: (({ editor }: { editor: any }) => void) | null = null;
let selectionUpdateHandler: (({ editor }: { editor: any }) => void) | null =
  null;
let transactionHandler:
  | (({ editor, transaction }: { editor: any; transaction: any }) => void)
  | null = null;
let focusHandler:
  | (({ editor, event }: { editor: any; event: FocusEvent }) => void)
  | null = null;
let blurHandler:
  | (({ editor, event }: { editor: any; event: FocusEvent }) => void)
  | null = null;
let destroyHandler: (() => void) | null = null;

watch(
  () => editor.value,
  (newEditor, oldEditor) => {
    // 清理旧编辑器的监听器
    if (oldEditor) {
      if (createHandler) oldEditor.off("create", createHandler);
      if (updateHandler) oldEditor.off("update", updateHandler);
      if (selectionUpdateHandler)
        oldEditor.off("selectionUpdate", selectionUpdateHandler);
      if (transactionHandler) oldEditor.off("transaction", transactionHandler);
      if (focusHandler) oldEditor.off("focus", focusHandler);
      if (blurHandler) oldEditor.off("blur", blurHandler);
      if (destroyHandler) oldEditor.off("destroy", destroyHandler);
    }

    if (!newEditor) {
      // 置空引用
      createHandler = null;
      updateHandler = null;
      selectionUpdateHandler = null;
      transactionHandler = null;
      focusHandler = null;
      blurHandler = null;
      destroyHandler = null;
      return;
    }

    // 创建事件处理函数并保存引用
    createHandler = ({ editor }) => {
      destroyed.value = false;
      emits("created", { editor });
    };
    updateHandler = ({ editor }) => {
      emits("changed", { editor });
      contentUpdated.value = true;
    };
    selectionUpdateHandler = ({ editor }) => {
      emits("changed:selection", { editor });
    };
    transactionHandler = ({ editor, transaction }) => {
      emits("changed:transaction", { editor, transaction });
    };
    focusHandler = ({ editor, event }) => {
      emits("focus", { editor, event });
    };
    blurHandler = ({ editor, event }) => {
      emits("blur", { editor, event });
    };
    destroyHandler = () => {
      emits("destroy");
    };

    // 添加新编辑器的事件监听器
    newEditor.on("create", createHandler);
    newEditor.on("update", updateHandler);
    newEditor.on("selectionUpdate", selectionUpdateHandler);
    newEditor.on("transaction", transactionHandler);
    newEditor.on("focus", focusHandler);
    newEditor.on("blur", blurHandler);
    newEditor.on("destroy", destroyHandler);
  }
);

// 页面布局变化监听
watch(
  () => page.value.layouts,
  (pageLayout: any, oldPageLayout: any) => {
    emits("changed:pageLayout", { pageLayout, oldPageLayout });
    addHistory(historyRecords.value, "page", {
      proType: "layouts",
      newData: pageLayout,
      oldData: oldPageLayout,
    });
  },
  { deep: true }
);

// 页面尺寸变化监听
watch(
  () => page.value.size,
  (pageSize: any, oldPageSize: any) => {
    emits("changed:pageSize", { pageSize, oldPageSize });
    addHistory(historyRecords.value, "page", {
      proType: "size",
      newData: pageSize,
      oldData: oldPageSize,
    });
  },
  { deep: true }
);

// 页面边距变化监听
watch(
  () => page.value.margin,
  (pageMargin: any, oldPageMargin: any) => {
    emits("changed:pageMargin", { pageMargin, oldPageMargin });
    addHistory(historyRecords.value, "page", {
      proType: "margin",
      newData: pageMargin,
      oldData: oldPageMargin,
    });
  },
  { deep: true }
);

// 页面背景变化监听
watch(
  () => page.value.background,
  (pageBackground, oldPageBackground) => {
    emits("changed:pageBackground", { pageBackground, oldPageBackground });
    addHistory(historyRecords.value, "page", {
      proType: "background",
      newData: pageBackground,
      oldData: oldPageBackground,
    });
  }
);

// 页面方向变化监听
watch(
  () => page.value.orientation,
  (pageOrientation, oldPageOrientation) => {
    emits("changed:pageOrientation", { pageOrientation, oldPageOrientation });
    addHistory(historyRecords.value, "page", {
      proType: "orientation",
      newData: pageOrientation,
      oldData: oldPageOrientation,
    });
  }
);

// 页面水印变化监听
watch(
  () => page.value.watermark,
  (pageWatermark: any, oldPageWatermark: any) => {
    emits("changed:pageWatermark", { pageWatermark, oldPageWatermark });
    addHistory(historyRecords.value, "page", {
      proType: "watermark",
      newData: pageWatermark,
      oldData: oldPageWatermark,
    });
  },
  { deep: true }
);

// 工具函数
const clearAutoSaveInterval = () => {
  if (autoSaveInterval.value !== null) {
    clearInterval(autoSaveInterval.value);
    autoSaveInterval.value = null;
  }
};

// 撤销重做操作
const undoHistory = () => {
  undoHistoryRecord(historyRecords.value, function (record) {
    if (record?.type === "editor") {
      editor.value?.chain().focus().undo().run();
    } else if (record?.type === "page" && record?.proType) {
      // 撤销
      if (page.value && record.oldData !== undefined) {
        (page.value as any)[record.proType] = record.oldData;
      }
    }
  });
};

const redoHistory = () => {
  redoHistoryRecord(historyRecords.value, function (record) {
    if (record?.type === "editor") {
      editor.value?.chain().focus().redo().run();
    } else if (record?.type === "page" && record?.proType) {
      // 恢复
      if (page.value && record.newData !== undefined) {
        (page.value as any)[record.proType] = record.newData;
      }
    }
  });
};

// 内容保存
const saveContent = async () => {
  if (props.document?.readOnly) {
    return;
  }
  try {
    const success = await props?.onSave?.(
      {
        html: editor.value?.getHTML() || "",
        json: editor.value?.getJSON() || {},
        text: editor.value?.getText() || "",
      },
      page.value,
      props.document || {}
    );
    if (success) {
      emits("saved");
      const time = new Date();
      savedAt.value = time;
    }
  } catch (e: unknown) {
    console.error((e as Error).message);
  }
};

// 获取内容
const getContent = <T extends "html" | "json" | "text" = "html">(
  format: T = "html" as T
): T extends "json" ? any : string => {
  if (!editor.value) {
    throw new Error("editor is not ready!");
  }
  if (format === "html") {
    return editor.value.getHTML() as T extends "json" ? any : string;
  }
  if (format === "text") {
    return editor.value.getText() as T extends "json" ? any : string;
  }
  if (format === "json") {
    return editor.value.getJSON() as T extends "json" ? any : string;
  }
  throw new Error("format must be html, text or json");
};

// 设置内容
const setContent = (
  content: any,
  options: any = {
    emitUpdate: true,
    focusPosition: "start",
    focusOptions: { scrollIntoView: true },
  }
) => {
  if (!editor.value) {
    throw new Error("editor is not ready!");
  }
  editor.value
    .chain()
    .setContent(content, options.emitUpdate)
    .focus(options.focusPosition, options.focusOptions)
    .run();
};

// 插入内容
const insertContent = (
  content: any,
  options: any = {
    updateSelection: true,
    focusPosition: "start",
    focusOptions: { scrollIntoView: true },
  }
) => {
  if (!editor.value) {
    throw new Error("editor is not ready!");
  }
  editor.value
    .chain()
    .insertContent(content, { updateSelection: options.updateSelection })
    .focus(options.focusPosition, options.focusOptions)
    .run();
};

// 焦点管理
const focus = (
  position: "start" | "end" | "all" | number | boolean = "start",
  options = { scrollIntoView: true }
) => editor.value?.commands.focus(position, options);

const blur = () => editor.value?.chain().blur().run();

// 全屏切换
const toggleFullscreen = (isFullscreen?: boolean) => {
  if (isFullscreen !== undefined) {
    fullscreen.value = isFullscreen;
    return;
  }
  fullscreen.value = !fullscreen.value;
};

// 打印
const print = () => {
  if (props.disableExtensions?.includes("print") || editor.value?.isEmpty) {
    return;
  }
  if (!props.document?.readOnly) {
    emits("print");
  }
};

// 销毁编辑器
const destroy = () => {
  editor.value?.destroy();
  destroyed.value = true;
};

// 设置页面
const setPage = (params: {
  size?: string;
  orientation?: string;
  background?: string;
  layout?: "web" | "page";
}) => {
  if (params.size) {
    const size = props.dicts?.pageSizes?.find(
      (item: any) => item.label === params.size
    );
    if (size) {
      page.value.size = size;
    }
  }
  if (params.orientation) {
    if (["portrait", "landscape"].includes(params.orientation)) {
      page.value.orientation = params.orientation;
    }
  }
  if (params.background) {
    page.value.background = params.background;
  }
  if (params.layout) {
    if (props.page?.layouts?.includes(params.layout)) {
      page.value.layouts = [params.layout];
    }
  }
};

// 设置水印
const setWatermark = (params: any) => {
  page.value.watermark = { ...page.value.watermark, ...params };
};

// 设置文档
const setDocument = (params: any) => {
  if (params.title) {
    // 文档标题可以通过其他方式管理
    console.log("Document title:", params.title);
  }
  if (params.readOnly !== undefined) {
    editor.value?.setEditable(!params.readOnly);
  }
};

// 设置主题
const setThemeMode = (theme: Theme) => {
  setTheme(theme);
  emits("changed:theme", theme);
};

// 快捷键绑定
const bindHotkeys = () => {
  // 撤销重做
  const handleUndo = () => undoHistory();
  const handleRedo = () => redoHistory();

  // 保存
  const handleSave = () => {
    void saveContent();
  };

  // 打印
  const handlePrint = () => {
    print();
  };

  // 全屏
  const handleFullscreen = () => {
    toggleFullscreen();
  };

  // 绑定键盘事件
  const handleKeydown = (e: KeyboardEvent) => {
    if (e.ctrlKey || e.metaKey) {
      switch (e.key) {
        case "z":
          e.preventDefault();
          if (e.shiftKey) {
            handleRedo();
          } else {
            handleUndo();
          }
          break;
        case "y":
          e.preventDefault();
          handleRedo();
          break;
        case "s":
          e.preventDefault();
          handleSave();
          break;
        case "p":
          e.preventDefault();
          handlePrint();
          break;
        case "f":
          e.preventDefault();
          // 搜索功能
          break;
      }
    }
    if (e.key === "F11") {
      e.preventDefault();
      handleFullscreen();
    }
  };

  document.addEventListener("keydown", handleKeydown);

  return () => {
    document.removeEventListener("keydown", handleKeydown);
  };
};

// 绑定快捷键
onMounted(() => {
  const unbind = bindHotkeys();
  onBeforeUnmount(unbind);
});

// 处理批注选择
const handleSelectComment = (commentId: string) => {
  // 可以在这里添加额外的处理逻辑
  console.log("选中批注:", commentId);
};

// 暴露方法
defineExpose({
  getContent,
  setContent,
  insertContent,
  focus,
  blur,
  print,
  toggleFullscreen,
  saveContent,
  undoHistory,
  redoHistory,
  setPage,
  setWatermark,
  setDocument,
  setTheme: setThemeMode,
  getEditor: () => editor.value,
  destroy,
});
</script>

<style lang="scss" scoped>
@use "./styles/index.scss" as *;

/* 编辑器容器样式 */
.editor-container {
  width: 100%;
  height: 100%;
  min-height: 400px;
  display: flex;
  flex-direction: column;
  color: var(--editor-text-color);
  font-family: var(--editor-font-family);
  position: relative;
  background-color: var(--editor-container-background);

  /* 全屏模式 */
  &.editor-is-fullscreen {
    position: fixed !important;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9999;
  }

  /* 预览模式 */
  &.preview-mode {
    .editor-toolbar {
      display: none;
    }
  }
}

/* 工具栏样式 */
.editor-toolbar {
  background-color: var(--editor-color-white);
  border-bottom: 1px solid var(--editor-border-color);
  flex-shrink: 0;
  z-index: 10;
}

/* 主内容区域 */
.editor-main {
  flex: 1;
  background-color: var(--editor-container-background);
  overflow: hidden;
  max-width: 100vw;
  display: flex;
  flex-direction: row;
}

.editor-main-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
}

/* 页面容器 */
.editor-page-container {
  height: 100%;
  display: flex;
  position: relative;
}

.editor-page-content {
  padding: 20px 50px;
  box-sizing: border-box;
  flex: 1;
  scroll-behavior: smooth;
  box-shadow: var(--editor-shadow);
  margin: 0 auto;
}

/* A4纸张样式 */
.editor-page-paper {
  width: 210mm;
  min-height: 297mm;
  background-color: var(--editor-page-background);
  box-shadow: rgba(0, 0, 0, 0.06) 0px 0px 10px 0px,
    rgba(0, 0, 0, 0.04) 0px 0px 0px 1px;
  display: flex;
  flex-direction: column;
  position: relative;
  box-sizing: border-box;
  margin: 0 auto;
}

/* 页面边距区域 */
.editor-page-header,
.editor-page-footer {
  display: flex;
  justify-content: space-between;
  height: var(--editor-page-margin-top);
  overflow: hidden;
}

.editor-page-footer {
  height: var(--editor-page-margin-bottom);
}

/* 页面边距内容 */
.editor-page-header-content,
.editor-page-footer-content {
  flex: 1;
}

/* 页面主体内容 */
.editor-page-body {
  flex: 1;
  position: relative;
  box-sizing: border-box;
}

/* 页面角落装饰 */
.editor-page-corner {
  box-sizing: border-box;
  position: relative;
  z-index: 10;
  width: var(--editor-page-margin-left);
}

.editor-page-corner::after {
  position: absolute;
  content: "";
  display: block;
  height: 1cm;
  width: 1cm;
  border: solid 1px var(--editor-border-color-light);
}

.corner-tl::after {
  border-top: none;
  border-left: none;
  bottom: 0;
  right: 0;
}

.corner-tr::after {
  border-top: none;
  border-right: none;
  bottom: 0;
  left: 0;
}

.corner-bl::after {
  border-bottom: none;
  border-left: none;
  top: 0;
  right: 0;
}

.corner-br::after {
  border-bottom: none;
  border-right: none;
  top: 0;
  left: 0;
}

/* 状态栏样式已移至 footer.vue 组件 */

/* 自定义滚动条 */
.editor-page-container::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.editor-page-container::-webkit-scrollbar-track {
  background: var(--editor-container-background);
  border-radius: 4px;
}

.editor-page-container::-webkit-scrollbar-thumb {
  background: var(--editor-scrollbar-thumb-color);
  border-radius: 4px;
}

.editor-page-container::-webkit-scrollbar-thumb:hover {
  background: var(--editor-scrollbar-thumb-hover-color);
}

/* 打印时隐藏装饰元素 */
@media print {
  .editor-page-corner::after {
    opacity: 0;
  }
}
</style>
